perm filename FINAL.F76[206,LSP] blob
sn#365991 filedate 1978-07-10 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00003 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 .require "memo.pub[let,jmc]" source
C00006 00003 .<<solutions>>
C00012 ENDMK
C⊗;
.require "memo.pub[let,jmc]" source
.turn on "→"
CS206∂(30)FINAL EXAMINATION→FALL 1976
This examination is open book and notes.
Write LISP functions as follows except where something else is
requested. Either notation may be used.
1. %2noccurl[x,u]%1 is the number of occurrences of the S-expression
⊗x in the list ⊗u (at the top level).
Example: %2noccurl[%1(A) , ((A) B ((A)) (A) A)] = 2.
2. %2noccurs[x,y]%1 is the number of occurrences of the S-expression
⊗x in the S-expression ⊗y (anywhere).
Example: %2noccurs%1[(A) , ((A) B ((A)) (A) A)] = 4.
3. %2samefringe[x,y]%1 is true if ⊗x and ⊗y have the same atoms
in the same order. Thus
%2samefringe[%1((A.B).C) , (A.(B.C))].
Write ⊗samefringe without flattening the lists ⊗x and ⊗y.
4. We define
%2prina[e,l] ← qif qat e qthen e . l qelse %1LP . %2prina[qa e,
%1DOT%2 . prina[qd e, %1RP%2 . l]]%1.
so that
%2prina%1[(PLUS (TIMES A B) C),NIL] = (LP PLUS DOT LP LP TIMES
DOT LP A DOT LP B DOT NIL RP RP RP DOT LP C DOT NIL RP RP RP),
i.e. ⊗prina "prints" an S-expression in "dot" notation.
On the other hand
%2prinb%1[(PLUS (TIMES A B) C)] = (LP PLUS LP TIMES A B RP C RP),
i.e. ⊗prinb "prints" an S-expression in "list" notation.
Hint: The second argument in each case is a list of the items to follow
the "printout" of the first expression. It is there to make the
recursion work.
5. We have
%2drop u ← qif qn u qthen qNIL qelse <qa u> . drop qd u%1.
Prove that for all lists ⊗u and ⊗v
%2drop[u * v] = drop u * drop v%1.
6. A list structure is called compact if EQUAL subexpressions
are represented by the same list structure. Thus
.skip 4
is a compact version of
.skip 4
and both represent the S-expression ((A) A).
%2compact x%1 is a compact list structure EQUAL to ⊗x.
How does the running time of your ⊗compact depend on the size of
⊗x? How fast a version do you think can be written? How
would it work?
.<<solutions>>
.next page
.turn off "["
.turn off "{"
.TURN ON "→"
.turn on "α"
CS206∂(27)SOLUTIONS TO FINAL→FALL 1976
1. %2noccurl[x , u] ← qif qn u qthen 0 qelse [qif x = qa u qthen 1 qelse 0]
+ noccurl[x , qd u]%1.
2. %2noccurs[x , y] ← qif x = y qthen 1 qelse qif qat y qthen 0
qelse noccurs[x , qa y] + noccurs[x, qd y]%1.
3. There are many solutions to the %2samefringe%1 problem which has
been proposed as an example requiring co-routines. Here one of the
simplest:
%2samefringe[x, y] ← x %3eq %2y ∨ [¬%3at %2x ∧
¬%3at %2y ∧ same[gopher x, gopher y]]
%2same[x, y] ← %3a %2x %3eq a %3y ∧
%2samefringe[%3d %2 x, %3d %2y]
%2gopher u ← %3if at a %2u %3then%2 u
%3else%2 gopher %3aa %2u . [%3da %2u . %3d %2u]
%1
%2gopher%1 digs up the first atom in an S-expression, piling
up the %2cdr%1s (with its hind legs) so that the indexing
through the atoms can be continued.
.nofill
4. %2prinb[e, l] ← qif qat e qthen e . l
∂(15)qelse %1LP%2 .
∂(20)[qif qn qd e qthen prinb[qa e, %1RP%2 . l]
∂(25)qelse qif qat qd e qthen prinb[qa e, %1DOT%2 . [qd e . [%1RP%2 . l]]]
∂(25)qelse prinb[qa e, qd prinb[qd e, l]]]%1
.fill
5. Let %2P(u)%1 be the assertion %2drop[u * v] = drop u * drop v%1. The
induction principle is
%2P[qnil] ∧ ∀u.[P[qd u] ⊃ P[u]] ⊃ ∀u.P[u]%1,
and putting %2P = λu.[drop[u * v] = drop u * drop v]%1 gives
.nofill
∂(10)%2[drop[qnil * v] = drop qnil * drop v]
∂(15)∧ ∀u.[drop[qd u * v] = drop qd u * drop v ⊃ drop[u * v] = drop u * drop v]
∂(10)⊃ ∀u.[drop[u * v] = drop u * drop v]%1.
.fill
We have
.nofill
%2drop[qnil * v] ∂(15)= drop v ∂(40)%1by %2∀w.qnil * w = w,
∂(15)= qnil * drop v ∂(40) %1by same fact,
∂(15)= drop qnil * drop v ∂(40)drop qnil = qnil %1comes from def. of %2drop%1,
and the last equation is %2P[qnil]%1. The induction step is
.skip to column 1
%2drop[u * v]∂(12) = drop[qif qn u qthen v qelse qa u .[q u * v]]→%1by def. %2u * v
∂(12)= qif qn u qthen drop v qelse drop[qa u . [qd u * v]]→%1by distrib. of c.e.%2
∂(12)= qif qn u qthen drop v qelse <qa [qa u . [qd u * v]]> . drop qd [qa u .[qd u * v]]
%1by def. of %2drop%1 and %2∀x y.¬qn[x . y]%1,
∂(12)= qif qn u qthen drop v qelse <qa u> . drop [qd u * v]→by qa and qd rules,%2
∂(12)= qif qn u qthen drop v qelse <qa u> . [drop qd u * drop v]→%1by induction hypothesis%2,
∂(12)= qif qn u qthen qnil * drop v qelse [<qa u> . drop qd u] * drop v
%1by %2∀w.[qnil * w = w]%1 and def. of %2[<qa u> . drop qd u] * drop v,
∂(12)= [qif qn u qthen qnil qelse <qa u> . drop qd u] * drop v→%1distrib. of c.e%2
∂(12)= drop u * drop v%1→%1by def. of %2drop v%1,
.fill
which is the result to be proved.
.nofill
6. %2compact x ← qa compact1[x, qnil]
compact1[x, u] ←∂(16){find[x, u]}[λz.
∂(20)qif ¬qn z qthen qa z . u
∂(20)qelse qif qat x qthen x . u
∂(20)qelse α{compact1[qa x, u]}[λx1.
∂(25){compact1[qd x, qd x1]}[λx2.
∂(30)qif qa x qeq qa x1 ∧ qd x qeq qa x2 qthen x . [x . qd x2]
∂(30)qelse α{qa x1 . qa x2}[λv. v . [v . qd x2]]]]]
find[x, u] ← qif qn u qthen qNIL qelse qif x = qa u qthen u qelse find[x, qd u]
.fill
%1
The following solution by Roy Harrington seems better than mine,
but I haven't taken time to analyze it:
.nofill
%2compact x ← comp[x, qNIL]
%2comp[x, y] ← ∂(13)qif qat x qthen x
∂(13)qelse {mem[x,y]}[λs.∂(30)qif ¬qn s qthen s
∂(30)qelse {comp[qd x, y]}[λz. comp[qa x, z . y] . z]]
mem[x, y] ← ∂(12)qif x = y qthen y
∂(12)qelse qif qat y qthen qNIL
∂(12)qelse {mem[x, qa y]}[λz. qif qn z qthen mem[x, qd y] qelse z]]